import 'dart:convert';

import 'package:dio/dio.dart';
import 'package:pax_info_app/net/result_data.dart';
import 'package:pax_info_app/utils/common_utils.dart';
import './code.dart';

import 'dart:collection';

import './interceptors/error_interceptor.dart';
import './interceptors/header_interceptor.dart';
import './interceptors/log_interceptor.dart';

import './interceptors/response_interceptor.dart';
import './interceptors/token_interceptor.dart';

///http请求
class HttpManager {
  static const CONTENT_TYPE_JSON = "application/json";
  static const CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";

  Dio dio = new Dio(); // 使用默认配置;
  static HttpManager? _instance;

  static HttpManager? getInstance() {
    if (_instance == null) {
      _instance = HttpManager();
    }
    return _instance;
  }

//  Dio dio = new Dio(); // 使用默认配置

  final TokenInterceptors _tokenInterceptors = new TokenInterceptors();

  HttpManager({bool withToken = true}) {
    dio.interceptors.add(new HeaderInterceptors());

    if (withToken) {
      dio.interceptors.add(_tokenInterceptors);
    }

    dio.interceptors.add(new LogsInterceptors());

    dio.interceptors.add(new ErrorInterceptors(dio));

    dio.interceptors.add(new ResponseInterceptors());
  }

  ///发起网络请求
  ///[ url] 请求url
  ///[ params] 请求参数
  ///[ header] 外加头
  ///[ option] 配置
  request(
      String url,
      HttpMethod method,
      { params,
        Map<String, dynamic>? header,
        Options? option,
        bool noTip = false
      }) async {
    Map<String, dynamic> headers = new HashMap();
    if (header != null) {
      headers.addAll(header);
    }

    if (option != null) {
      option.headers = headers;
    } else {
      option = new Options(method: HttpMethodValues[method]);
      option.headers = headers;
    }
    /// 添加请求时间 30S
    option.sendTimeout = 30000;

    resultError(DioError e) {
      Response? errorResponse;
      if (e.response != null) {
        errorResponse = e.response;
      } else {
        errorResponse = new Response(statusCode: 666, requestOptions: RequestOptions(path: url));
      }
      if (e.type == DioErrorType.connectTimeout ||
          e.type == DioErrorType.receiveTimeout) {
        errorResponse!.statusCode = Code.NETWORK_TIMEOUT;
      }
      return new ResultData(
          Code.errorHandleFunction(errorResponse!.statusCode, e.message, noTip),
          false,
          errorResponse.statusCode);
    }

    Response response;
    try {
      response = await dio.request(url, data: params, options: option);

      var responseJson = response.data;
      var result = jsonDecode(responseJson.data);
      print('== responseJson: ${result}');
      if (result['Code'] != 0) {
        if (!noTip) {
          // CommonUtils.toastShort(msg: responseJson.data['msg']);
          await Code.errorHandleFunction(result['Code'], result['Message'], noTip);
        }
      }
    } on DioError catch (e) {
      return resultError(e);
    }
    if (response.data is DioError) {
      return resultError(response.data);
    }
    return response.data;
  }

  ///清除授权
  clearAuthorization() {
    // _tokenInterceptors.clearAuthorization();
  }

  ///获取授权token
  getAuthorization() async {
    // return _tokenInterceptors.getAuthorization();
  }
}

final HttpManager httpManager = new HttpManager();
final HttpManager httpManagerNoToken = new HttpManager(withToken: false);

enum HttpMethod {
  GET,
  POST,
  DELETE,
  PUT,
  PATCH,
}
//使用：HttpMethodValues[HttpMethod.POST]
const HttpMethodValues = {
  HttpMethod.GET: "get",
  HttpMethod.POST: "post",
  HttpMethod.DELETE: "delete",
  HttpMethod.PUT: "put",
  HttpMethod.PATCH: "patch",
};

/// 接口的code没有返回为true的异常
class NotSuccessException implements Exception {
  String? message;

  // NotSuccessException.fromRespData(BaseResponseData respData) {
  //   message = respData.message;
  // }

  @override
  String toString() {
    return 'NotExpectedException{respData: $message}';
  }
}

/// 用于未登录等权限不够,需要跳转授权页面
class UnAuthorizedException implements Exception {
  const UnAuthorizedException();

  @override
  String toString() => 'UnAuthorizedException';
}
